package com.putong35.common.utils.ui;

import android.content.Context;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;

import com.google.android.flexbox.FlexboxLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * 配套FlexboxLayout一起使用的控制器类，用来控制单选和多选
 * 默认是多选
 *
 * 不支持数据动态变化
 *
 * @Author: PengWeiwei
 * @E-mail: pengveivei@sina.cn
 * @CreateDate: 2017-04-14
 * @Version: 1.0.0
 */
public class FlexboxChooseControler {
    public enum Mode {Single, Multiple}

    private int dataCount = 0;
    /**
     * 保存所有的itemView，记录每个view的状态
     */
    private List<ViewState> viewStateList = new ArrayList<>();

    private Mode mode = Mode.Multiple;
    private FlexboxLayout flexboxLayout;
    private Context context;
    private
    @LayoutRes
    int itemLayoutId;

    private OnItemSelectedListener onItemSelectedListener;
    private OnItemViewInflatedListener onItemViewInflatedListener;

    public FlexboxChooseControler(Context context,
                                  int dataCount,
                                  FlexboxLayout flexboxLayout,
                                  @LayoutRes int itemLayoutId,
                                  Mode mode,
                                  @NonNull OnItemViewInflatedListener itemViewInflatedListener) {
        this.context = context;
        this.dataCount = dataCount;
        this.itemLayoutId = itemLayoutId;
        this.mode = mode;
        this.flexboxLayout = flexboxLayout;
        this.onItemViewInflatedListener = itemViewInflatedListener;
        fillFlexbox();
    }

    public FlexboxChooseControler(Context context,
                                  int dataCount,
                                  FlexboxLayout flexboxLayout,
                                  @LayoutRes int itemLayoutId,
                                  @NonNull OnItemViewInflatedListener itemViewInflatedListener) {
        this(context, dataCount, flexboxLayout, itemLayoutId, Mode.Multiple, itemViewInflatedListener);
    }


    private void fillFlexbox() {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        for (int i = 0 ; i < dataCount; i++) {
            View itemView = inflater.inflate(itemLayoutId, flexboxLayout, false);
            if (onItemViewInflatedListener != null) {
                onItemViewInflatedListener.onInflated(i, itemView);
            }
            flexboxLayout.addView(itemView);
            ViewState viewState = new ViewState(itemView, false);
            selectItemView(viewState, false);
            viewStateList.add(viewState);

            itemView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // 不能用view.isPress来判断， press在click之前就执行了。
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        ViewState viewState = getViewState(v);
                        if (viewState.selected) {
                            selectItemView(viewState, false);
                        } else {
                            selectItemView(viewState, true);
                        }
                    }
                    return true;
                }
            });

        }

    }


    public List<Integer> getSeletedItemPositions() {
        List<Integer> list = new ArrayList<>();
        for (int i = 0 ; i < viewStateList.size(); i++) {
            ViewState viewState = viewStateList.get(i);
            if (viewState.selected) {
                list.add(i);
            }
        }
        return list;
    }

    public void select(@NonNull int... dataPosis) {
        if (mode == Mode.Single && dataPosis.length > 1) {
            Log.w("FlexboxChooseChontroler", "单选模式不要设置多个check值，如果设置则取最后一个");
        }

        for (int posi : dataPosis) {
            ViewState viewState = viewStateList.get(posi);
            selectItemView(viewState, true);
        }
    }

    private void selectItemView(ViewState viewState, boolean selected) {
        // 对单选模式特别处理，选中某个item之后，其他的item都要unselected
        if (mode == Mode.Single) {
            if (selected) {
                for (ViewState viewState1 : viewStateList) {
                    if (viewState1 != viewState && viewState1.selected) {
                        viewState1.selected = false;
                        viewState1.itemView.setSelected(false);
                    }
                }
                viewState.selected = true;
                viewState.itemView.setSelected(true);
                if (onItemSelectedListener != null) {
                    onItemSelectedListener.onSelected(getItemViewPosition(viewState.itemView), viewState.itemView, true);
                }
            } else {
                // 保证存在一个选项，不接受selected == false
            }
        } else {
            viewState.selected = selected;
            viewState.itemView.setSelected(selected);
            if (onItemSelectedListener != null) {
                onItemSelectedListener.onSelected(getItemViewPosition(viewState.itemView), viewState.itemView, selected);
            }
        }
    }

    public boolean isItemSelected(View itemView) {
        for (ViewState viewState : viewStateList) {
            if (viewState.itemView == itemView && viewState.selected) {
                return true;
            }
        }
        return false;
    }


    public ViewState getViewState(View itemView) {
        for (ViewState viewState : viewStateList) {
            if (viewState.itemView == itemView) {
                return viewState;
            }
        }
        return null;
    }

    public int getItemViewPosition(View itemView) {
        for (int i = 0; i < viewStateList.size(); i++) {
            if (viewStateList.get(i).itemView == itemView) {
                return i;
            }
        }
        return -1;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    public Mode getMode() {
        return mode;
    }

    public void setOnItemSelectedListener(OnItemSelectedListener itemSelectedListener) {
        this.onItemSelectedListener = itemSelectedListener;
    }

    /**
     * item 被选中时回调
     */
    public interface OnItemSelectedListener {
        void onSelected(int position, View itemView, boolean selected);
    }

    /**
     * item view 被inflated或者created之后回调
     */
    public interface OnItemViewInflatedListener  {
        void onInflated(int position, View itemView);
    }

    public static class ViewState {
        public ViewState(View itemView, boolean selected) {
            this.itemView = itemView;
            this.selected = selected;
        }
        View itemView;
        boolean selected;
    }

}
